<!doctype html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
    <link rel="stylesheet" href="common/emscripten.css"/>
    <link rel="stylesheet" href="common/testing.css"/>
    <title>speedtest1.wasm</title>
  </head>
  <body>
    <header id='titlebar'><span>speedtest1.wasm</span></header>
    <div>See also: <a href='speedtest1-worker.html'>A Worker-thread variant of this page.</a></div>
    <!-- emscripten bits -->
    <figure id="module-spinner">
      <div class="spinner"></div>
      <div class='center'><strong>Initializing app...</strong></div>
      <div class='center'>
        On a slow internet connection this may take a moment.  If this
        message displays for "a long time", intialization may have
        failed and the JavaScript console may contain clues as to why.
      </div>
    </figure>
    <div class="emscripten" id="module-status">Downloading...</div>
    <div class="emscripten">
      <progress value="0" max="100" id="module-progress" hidden='1'></progress>  
    </div><!-- /emscripten bits -->
    <div class='warning'>This page starts running the main exe when it loads, which will
      block the UI until it finishes! Adding UI controls to manually configure and start it
      are TODO.</div>
    </div>
    <div class='warning'>Achtung: running it with the dev tools open may
      <em>drastically</em> slow it down. For faster results, keep the dev
      tools closed when running it!
    </div>
    <div>Output is delayed/buffered because we cannot update the UI while the
      speedtest is running. Output will appear below when ready...
    <div id='test-output'></div>
    <script src="common/SqliteTestUtil.js"></script>
    <script src="jswasm/speedtest1.js"></script>
    <script>(function(){
    /**
       If this environment contains WASMFS with OPFS, this function
       initializes it and returns the name of the dir on which OPFS is
       mounted, else it returns an empty string.
    */
    const wasmfsDir = function f(wasmUtil){
        if(undefined !== f._) return f._;
        const pdir = '/persistent';
        if( !self.FileSystemHandle
            || !self.FileSystemDirectoryHandle
            || !self.FileSystemFileHandle){
            return f._ = "";
        }
        try{
            if(0===wasmUtil.xCallWrapped(
                'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
            )){
                return f._ = pdir;
            }else{
                return f._ = "";
            }
        }catch(e){
            // sqlite3_wasm_init_wasmfs() is not available
            return f._ = "";
        }
    };
    wasmfsDir._ = undefined;

    const eOut = document.querySelector('#test-output');
    const log2 = function(cssClass,...args){
        const ln = document.createElement('div');
        if(cssClass) ln.classList.add(cssClass);
        ln.append(document.createTextNode(args.join(' ')));
        eOut.append(ln);
        //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
    };
    const logList = [];
    const dumpLogList = function(){
        logList.forEach((v)=>log2('',v));
        logList.length = 0;
    };
    /* can't update DOM while speedtest is running unless we run
       speedtest in a worker thread. */;
    const log = (...args)=>{
        console.log(...args);
        logList.push(args.join(' '));
    };
    const logErr = function(...args){
        console.error(...args);
        logList.push('ERROR: '+args.join(' '));
    };

    const runTests = function(sqlite3){
        const capi = sqlite3.capi, wasm = sqlite3.wasm;
        //console.debug('sqlite3 =',sqlite3);
        const pDir = wasmfsDir(wasm);
        if(pDir){
            console.warn("Persistent storage:",pDir);
        }
        const scope = wasm.scopedAllocPush();
        let dbFile = pDir+"/speedtest1.db";
        const urlParams = new URL(self.location.href).searchParams;
        const argv = ["speedtest1"];
        if(urlParams.has('flags')){
            argv.push(...(urlParams.get('flags').split(',')));
        }

        let forceSize = 0;
        let vfs, pVfs = 0;
        if(urlParams.has('vfs')){
            vfs = urlParams.get('vfs');
            pVfs = capi.sqlite3_vfs_find(vfs);
            if(!pVfs){
                log2('error',"Unknown VFS:",vfs);
                return;
            }
            argv.push("--vfs", vfs);
            log2('',"Using VFS:",vfs);
            if('kvvfs' === vfs){
                forceSize = 4 /* 5 uses approx. 4.96mb */;
                dbFile = 'session';
                log2('warning',"kvvfs VFS: forcing --size",forceSize,
                     "and filename '"+dbFile+"'.");
                capi.sqlite3_js_kvvfs_clear(dbFile);
            }
        }
        if(forceSize){
            argv.push('--size',forceSize);
        }else{
            [
                'size'
            ].forEach(function(k){
                const v = urlParams.get(k);
                if(v) argv.push('--'+k, urlParams[k]);
            });
        }
        argv.push(
            "--singlethread",
            //"--nomutex",
            //"--nosync",
            //"--memdb", // note that memdb trumps the filename arg
            "--nomemstat"
        );
        argv.push("--big-transactions"/*important for tests 410 and 510!*/,
                  dbFile);
        console.log("argv =",argv);
        // These log messages are not emitted to the UI until after main() returns. Fixing that
        // requires moving the main() call and related cleanup into a timeout handler.
        if(pDir) wasm.sqlite3_wasm_vfs_unlink(pVfs,dbFile);
        log2('',"Starting native app:\n ",argv.join(' '));
        log2('',"This will take a while and the browser might warn about the runaway JS.",
             "Give it time...");
        logList.length = 0;
        setTimeout(function(){
            wasm.xCall('wasm_main', argv.length,
                       wasm.scopedAllocMainArgv(argv));
            wasm.scopedAllocPop(scope);
            if('kvvfs'===vfs){
                logList.unshift("KVVFS "+dbFile+" size = "+
                                capi.sqlite3_js_kvvfs_size(dbFile));
            }
            if(pDir) wasm.sqlite3_wasm_vfs_unlink(pVfs,dbFile);
            logList.unshift("Done running native main(). Output:");
            dumpLogList();
        }, 50);
    }/*runTests()*/;

    self.sqlite3TestModule.print = log;
    self.sqlite3TestModule.printErr = logErr;
    sqlite3InitModule(self.sqlite3TestModule).then(runTests);
})();</script>
</body>
</html>
